home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / samba.idb / usr / samba / src / source / md4.c.z / md4.c
Encoding:
C/C++ Source or Header  |  1998-10-28  |  4.2 KB  |  172 lines

  1. /* 
  2.    Unix SMB/Netbios implementation.
  3.    Version 1.9.
  4.    a implementation of MD4 designed for use in the SMB authentication protocol
  5.    Copyright (C) Andrew Tridgell 1997-1998.
  6.    
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 2 of the License, or
  10.    (at your option) any later version.
  11.    
  12.    This program is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.    
  17.    You should have received a copy of the GNU General Public License
  18.    along with this program; if not, write to the Free Software
  19.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21.  
  22.  
  23. /* NOTE: This code makes no attempt to be fast! 
  24.  
  25.    It assumes that a int is at least 32 bits long
  26. */
  27.  
  28. typedef unsigned int uint32;
  29.  
  30. static uint32 A, B, C, D;
  31.  
  32. static uint32 F(uint32 X, uint32 Y, uint32 Z)
  33. {
  34.     return (X&Y) | ((~X)&Z);
  35. }
  36.  
  37. static uint32 G(uint32 X, uint32 Y, uint32 Z)
  38. {
  39.     return (X&Y) | (X&Z) | (Y&Z); 
  40. }
  41.  
  42. static uint32 H(uint32 X, uint32 Y, uint32 Z)
  43. {
  44.     return X^Y^Z;
  45. }
  46.  
  47. static uint32 lshift(uint32 x, int s)
  48. {
  49.     x &= 0xFFFFFFFF;
  50.     return ((x<<s)&0xFFFFFFFF) | (x>>(32-s));
  51. }
  52.  
  53. #define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s)
  54. #define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + (uint32)0x5A827999,s)
  55. #define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (uint32)0x6ED9EBA1,s)
  56.  
  57. /* this applies md4 to 64 byte chunks */
  58. static void mdfour64(uint32 *M)
  59. {
  60.     int j;
  61.     uint32 AA, BB, CC, DD;
  62.     uint32 X[16];
  63.  
  64.     for (j=0;j<16;j++)
  65.         X[j] = M[j];
  66.  
  67.     AA = A; BB = B; CC = C; DD = D;
  68.  
  69.         ROUND1(A,B,C,D,  0,  3);  ROUND1(D,A,B,C,  1,  7);  
  70.     ROUND1(C,D,A,B,  2, 11);  ROUND1(B,C,D,A,  3, 19);
  71.         ROUND1(A,B,C,D,  4,  3);  ROUND1(D,A,B,C,  5,  7);  
  72.     ROUND1(C,D,A,B,  6, 11);  ROUND1(B,C,D,A,  7, 19);
  73.         ROUND1(A,B,C,D,  8,  3);  ROUND1(D,A,B,C,  9,  7);  
  74.     ROUND1(C,D,A,B, 10, 11);  ROUND1(B,C,D,A, 11, 19);
  75.         ROUND1(A,B,C,D, 12,  3);  ROUND1(D,A,B,C, 13,  7);  
  76.     ROUND1(C,D,A,B, 14, 11);  ROUND1(B,C,D,A, 15, 19);    
  77.  
  78.         ROUND2(A,B,C,D,  0,  3);  ROUND2(D,A,B,C,  4,  5);  
  79.     ROUND2(C,D,A,B,  8,  9);  ROUND2(B,C,D,A, 12, 13);
  80.         ROUND2(A,B,C,D,  1,  3);  ROUND2(D,A,B,C,  5,  5);  
  81.     ROUND2(C,D,A,B,  9,  9);  ROUND2(B,C,D,A, 13, 13);
  82.         ROUND2(A,B,C,D,  2,  3);  ROUND2(D,A,B,C,  6,  5);  
  83.     ROUND2(C,D,A,B, 10,  9);  ROUND2(B,C,D,A, 14, 13);
  84.         ROUND2(A,B,C,D,  3,  3);  ROUND2(D,A,B,C,  7,  5);  
  85.     ROUND2(C,D,A,B, 11,  9);  ROUND2(B,C,D,A, 15, 13);
  86.  
  87.     ROUND3(A,B,C,D,  0,  3);  ROUND3(D,A,B,C,  8,  9);  
  88.     ROUND3(C,D,A,B,  4, 11);  ROUND3(B,C,D,A, 12, 15);
  89.         ROUND3(A,B,C,D,  2,  3);  ROUND3(D,A,B,C, 10,  9);  
  90.     ROUND3(C,D,A,B,  6, 11);  ROUND3(B,C,D,A, 14, 15);
  91.         ROUND3(A,B,C,D,  1,  3);  ROUND3(D,A,B,C,  9,  9);  
  92.     ROUND3(C,D,A,B,  5, 11);  ROUND3(B,C,D,A, 13, 15);
  93.         ROUND3(A,B,C,D,  3,  3);  ROUND3(D,A,B,C, 11,  9);  
  94.     ROUND3(C,D,A,B,  7, 11);  ROUND3(B,C,D,A, 15, 15);
  95.  
  96.     A += AA; B += BB; C += CC; D += DD;
  97.     
  98.     A &= 0xFFFFFFFF; B &= 0xFFFFFFFF;
  99.     C &= 0xFFFFFFFF; D &= 0xFFFFFFFF;
  100.  
  101.     for (j=0;j<16;j++)
  102.         X[j] = 0;
  103. }
  104.  
  105. static void copy64(uint32 *M, unsigned char *in)
  106. {
  107.     int i;
  108.  
  109.     for (i=0;i<16;i++)
  110.         M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) |
  111.             (in[i*4+1]<<8) | (in[i*4+0]<<0);
  112. }
  113.  
  114. static void copy4(unsigned char *out,uint32 x)
  115. {
  116.     out[0] = x&0xFF;
  117.     out[1] = (x>>8)&0xFF;
  118.     out[2] = (x>>16)&0xFF;
  119.     out[3] = (x>>24)&0xFF;
  120. }
  121.  
  122. /* produce a md4 message digest from data of length n bytes */
  123. void mdfour(unsigned char *out, unsigned char *in, int n)
  124. {
  125.     unsigned char buf[128];
  126.     uint32 M[16];
  127.     uint32 b = n * 8;
  128.     int i;
  129.  
  130.     A = 0x67452301;
  131.     B = 0xefcdab89;
  132.     C = 0x98badcfe;
  133.     D = 0x10325476;
  134.  
  135.     while (n > 64) {
  136.         copy64(M, in);
  137.         mdfour64(M);
  138.         in += 64;
  139.         n -= 64;
  140.     }
  141.  
  142.     for (i=0;i<128;i++)
  143.         buf[i] = 0;
  144.     memcpy(buf, in, n);
  145.     buf[n] = 0x80;
  146.     
  147.     if (n <= 55) {
  148.         copy4(buf+56, b);
  149.         copy64(M, buf);
  150.         mdfour64(M);
  151.     } else {
  152.         copy4(buf+120, b); 
  153.         copy64(M, buf);
  154.         mdfour64(M);
  155.         copy64(M, buf+64);
  156.         mdfour64(M);
  157.     }
  158.  
  159.     for (i=0;i<128;i++)
  160.         buf[i] = 0;
  161.     copy64(M, buf);
  162.  
  163.     copy4(out, A);
  164.     copy4(out+4, B);
  165.     copy4(out+8, C);
  166.     copy4(out+12, D);
  167.  
  168.     A = B = C = D = 0;
  169. }
  170.  
  171.  
  172.